import 'dart:async';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:moose_app/core/constants/auth_constant.dart';
import 'package:moose_app/core/constants/system_constant.dart';
import 'package:moose_app/core/model/base_response.dart';
import 'package:moose_app/core/utils/logger.dart';
import 'package:moose_app/core/utils/sp_util.dart';

enum Method { get, post }

class RequestManager {
  static const CONTENT_TYPE_JSON = "application/json";
  static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";

  factory RequestManager() => _getInstance();

  static RequestManager get instance => _getInstance();

  static RequestManager _instance;

  Dio _dio;

  RequestManager._internal() {
    ///       初始化
    _dio = Dio(BaseOptions(
        connectTimeout: 10000,
        receiveTimeout: 10000,
        baseUrl: Platform.isIOS ? IOS_URL : ANDROID_URL));
  }

  static RequestManager _getInstance() {
    if (_instance == null) {
      _instance = RequestManager._internal();
    }
    return _instance;
  }

  Future<BaseResponse> get(String url,
      {bool auth = true, Map<String, dynamic> params}) {
    return _doRequest(url, params, Method.get, auth: auth);
  }

  Future<BaseResponse> post(String url,
      {bool auth = true, Map<String, dynamic> params}) {
    return _doRequest(url, params, Method.post, auth: auth);
  }

  Future<BaseResponse> _doRequest(
      String url, Map<String, dynamic> params, Method method,
      {bool auth}) async {
    try {
      Response response;
      Map<String, dynamic> headers = Map();
      if (auth) {
        String accessToken =
            ATHSpUtil.getString(AUTH_ACCESS_TOKEN, defValue: "");
        headers['Authorization'] = "Bearer $accessToken";
      }
      Options options = Options(headers: headers);
      switch (method) {
        case Method.get:
          if (params != null && params.isNotEmpty) {
            response =
                await _dio.get(url, options: options, queryParameters: params);
          } else {
            response = await _dio.get(url, options: options);
          }
          break;
        case Method.post:
          if (params != null && params.isNotEmpty) {
            response =
                await _dio.post(url, options: options, queryParameters: params);
          } else {
            response = await _dio.post(url, options: options);
          }
          break;
      }

      // print('''url: $url\n response: ${response}''');

      if (response.statusCode != 200) {
        ATHLogger.e("dio response error :: ", response.toString());
        EasyLoading.showToast("请求失败，网络异常，${response.statusMessage}");
        return BaseResponse(response.statusCode, response.statusMessage, null);
      }
      BaseResponse result = BaseResponse.fromJson(response.data);
      if (result.code != 200) {
        ATHLogger.e("base response error :: ", result.toJson());
        return BaseResponse(result.code, result.message, null);
      }
      return result;
    } catch (exception) {
      ATHLogger.e('''catch dio exception : $url''', exception.toString());
      EasyLoading.showToast("请求失败，网络异常，${exception.toString()}");
      return BaseResponse(-1, "请求失败，网络异常 ${exception.toString()}", null);
    } finally {
      Timer.periodic(Duration(seconds: 3), (timer) {
        EasyLoading.dismiss(animation: true);
      });
    }
  }
}
